package gmomo;

import gmomo.packet.Invitation;

import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;

public class PacketListenerImpl implements PacketListener {
	
	private HashSet<MessageListener> msgListeners;
	private HashSet<InvitationListener> invitationListeners;
	private HashSet<PresenceListener> presenceListeners;
	private ExecutorService executor;
	
	public PacketListenerImpl() {
		msgListeners = new HashSet<MessageListener>();
		invitationListeners = new HashSet<InvitationListener>();
		presenceListeners = new HashSet<PresenceListener>();
		executor = Executors.newSingleThreadExecutor();
	}

	public void processPacket(Packet packet) {
		executor.submit(new PacketProcessor(packet));
	}
	
	public void addMessageListener(MessageListener listener) {
		msgListeners.add(listener);
	}
	
	public void removeMessageListener(MessageListener listener) {
		msgListeners.remove(listener);
	}
	
	public void addInvitationListener(InvitationListener listener) {
		invitationListeners.add(listener);
	}
	
	public void removeInvitationListener(InvitationListener listener) {
		invitationListeners.remove(listener);
	}
	
	public void addPresenceListener(PresenceListener listener) {
		presenceListeners.add(listener);
	}
	
	public void removePresenceListener(PresenceListener listener) {
		presenceListeners.remove(listener);
	}
	
	private class PacketProcessor implements Runnable {
		
		private Packet packet;
		
		public PacketProcessor(Packet packet) {
			this.packet = packet;
		}
		
		public boolean isInvitationMessage(Packet packet) {
			String type = (String)packet.getProperty("GMoMoType");
			if ( type == null )
				return false;
			return type.equals("invitation");
		}

		public void run() {
			if ( packet instanceof Presence ) {
				for ( PresenceListener listener : presenceListeners )
					listener.presenceChanged((Presence)packet);
			}else if ( packet instanceof Message ) {
				System.out.println(packet.toXML());
				if ( isInvitationMessage(packet) ) {
					Invitation invite = new Invitation((Message)packet);
					for ( InvitationListener listener : invitationListeners )
						listener.invitationReceived( invite );
				}else {
					for ( MessageListener listener : msgListeners )
						listener.messageReceived((Message)packet);
				}
			}
		}
	}
}
